package com.xmindguoguo.boot.core.log.factory;

import java.lang.reflect.Method;
import java.util.Date;
import java.util.Objects;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang.exception.ExceptionUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.method.HandlerMethod;

import com.alibaba.fastjson.JSON;
import com.xmindguoguo.boot.common.annotation.OperationLog;
import com.xmindguoguo.boot.common.constant.GlobalConstant;
import com.xmindguoguo.boot.core.shiro.ShiroKit;
import com.xmindguoguo.boot.modular.system.model.TSystemErrorLogModel;
import com.xmindguoguo.boot.modular.system.model.TSystemLoginLogModel;
import com.xmindguoguo.boot.modular.system.model.TSystemOperationLogModel;
import com.xmindguoguo.boot.util.CmUtil;
import com.xmindguoguo.boot.util.ConvertUtil;
import com.xmindguoguo.boot.util.http.AddressUtils;
import com.xmindguoguo.boot.util.http.HttpUtil;
import com.xmindguoguo.boot.util.http.IpUtils;

/**
 * 日志对象创建工厂
 *
 * @author fengshuonan
 * @date 2016年12月6日 下午9:18:27
 */
public class LogModelFactory {
    /**
     * 创建登录日志 不能使用request 来进行，因为没有访问的请求
     * 
     * @Title getTSystemLoginLogModel
     * @author 于国帅
     * @date 2019年1月31日 下午3:40:23
     * @param username
     * @param password
     * @param msg
     *            void
     */
    public static TSystemLoginLogModel getTSystemLoginLogModel(String ip, String userAgentStr, String username, String password,
            String msg) {
        TSystemLoginLogModel systemLoginLogModel = new TSystemLoginLogModel();
        systemLoginLogModel.setId(CmUtil.getPkId());
        systemLoginLogModel.setAccount(username);
        systemLoginLogModel.setParams("password:" + password);
        systemLoginLogModel.setLoginUserId(ShiroKit.getUserId());
        systemLoginLogModel.setTips(msg);
        systemLoginLogModel.setIp(ip);
        // 整理根据iP查询地址
        systemLoginLogModel.setAddress(AddressUtils.getRealAddressByIP(systemLoginLogModel.getIp()));
        systemLoginLogModel.setUserAgentStr(userAgentStr);
        systemLoginLogModel.setCreateTime(new Date());
        // 是否登录成功
        if (msg.equals("登陆成功")) {
            systemLoginLogModel.setStatus(GlobalConstant.LOGIN_STATUS.SUCCESS);
        } else {
            systemLoginLogModel.setStatus(GlobalConstant.LOGIN_STATUS.FIAL);
        }
        return systemLoginLogModel;
    }

    /**
     * 创建错误日志
     * 
     * @Title getTSystemErrorLogModel
     * @author 于国帅
     * @date 2019年1月31日 下午4:34:16
     * @param request
     * @param handler
     * @param ex
     * @return TSystemErrorLogModel
     */
    public static TSystemErrorLogModel getTSystemErrorLogModel(HttpServletRequest request, Object handler, Exception ex) {
        TSystemErrorLogModel errorLogModel = new TSystemErrorLogModel();
        errorLogModel.setId(CmUtil.getPkId());
        errorLogModel.setReqUrl(request.getServletPath());
        if (Objects.nonNull(handler) && handler instanceof HandlerMethod) {
            HandlerMethod handlerMethod = (HandlerMethod) handler;
            errorLogModel.setClassTypeName(handlerMethod.getBeanType().toString());
            errorLogModel.setMethodName(handlerMethod.getMethod().getName());
            errorLogModel.setParams(HttpUtil.getRequestQueryString(request));
            errorLogModel.setMemo(handlerMethod.toString());
        }
        errorLogModel.setErrorName(ex.getMessage());
        errorLogModel.setErrorInfo(ExceptionUtils.getFullStackTrace(ex));
        errorLogModel.setIp(IpUtils.getIpAddr(request));
        // 整理根据iP查询地址
        errorLogModel.setAddress(AddressUtils.getRealAddressByIP(errorLogModel.getIp()));
        errorLogModel.setCreateTime(new Date());
        errorLogModel.setUserAgentStr(request.getHeader("User-Agent"));
        errorLogModel.setLoginUserId(ShiroKit.getUserId());
        errorLogModel.setAccount(ShiroKit.getUserAccount());
        return errorLogModel;
    }

    public static TSystemOperationLogModel getTSystemOperationLogModel(ProceedingJoinPoint point, Object result, long executeTime) {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        MethodSignature signature = (MethodSignature) point.getSignature();
        Method method = signature.getMethod();
        OperationLog operationLog = method.getAnnotation(OperationLog.class);
        TSystemOperationLogModel model = new TSystemOperationLogModel();
        model.setId(CmUtil.getPkId());
        if (Objects.nonNull(operationLog)) {
            model.setLogName(operationLog.logName());
            model.setLogType(operationLog.operationLogType().ordinal());
            model.setReqUrl(request.getServletPath());
            model.setClassTypeName(method.getDeclaringClass().getName());
            model.setMethodName(method.getName());
            model.setParams(JSON.toJSONString(point.getArgs()));
            model.setOperationResult(JSON.toJSONString(result));
            model.setExecuteTime(ConvertUtil.objToString(executeTime));
            model.setIp(IpUtils.getIpAddr(request));
            model.setAddress(AddressUtils.getRealAddressByIP(model.getIp()));
            model.setUserAgentStr(request.getHeader("User-Agent"));
            model.setLoginUserId(ShiroKit.getUserId());
            model.setCreateTime(new Date());
            model.setAccount(ShiroKit.getUserAccount());
            if (Objects.nonNull(result)) {
                model.setOperationFlag(GlobalConstant.FLAG_STATUS.SUCCESS);
            } else {
                model.setOperationFlag(GlobalConstant.FLAG_STATUS.FIAL);
            }
        }
        return model;
    }
}
